package cn.pink.gamesrv;

import cn.pink.common.StatService;
import cn.pink.common.support.tools.cache.CacheTool;
import cn.pink.common.support.tools.cache.ICacheListener;
import cn.pink.common.support.tools.cache.RemoveReason;
import cn.pink.common.support.tools.node.NodeTool;
import cn.pink.core.Node;
import cn.pink.core.NodeInfo;
import cn.pink.core.NodeType;
import cn.pink.core.config.CacheConfig;
import cn.pink.core.config.IronConfig;
import cn.pink.gamesrv.account.AccountService;
import cn.pink.gamesrv.human.HumanObjectService;
import io.vertx.core.Promise;

import java.util.List;

/**
 * 游戏服节点
 * @Author: pink
 * @Date: 2022/5/19 11:56
 */
public class GameNode extends Node {
    @Override
    public void start(Promise<Void> startPromise) {
        try {
            port = new GamePort(String.valueOf(Thread.currentThread().getId()));
            port.startup(this, false);

            port.addService(new GameService(port));
            port.addService(new AccountService(port));

            //启动运行信息统计
            if (IronConfig.STAT_ENABLE) {
                port.addService(new StatService(port));
            }

            registerListener();

            NodeTool.getInstance().registerNode(getId(), port.getId(), NodeType.GAME).onSuccess(v -> super.start(startPromise));
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void stop() {
        super.stop();
    }

    @Override
    public void registerListener() {
        CacheTool.getInstance().registerListener(CacheConfig.NODE, new ICacheListener() {
            @Override
            public void elementAdd(String key, Object value) {

            }

            @Override
            public void elementUpdate(String key, Object value, Object oldValue) {

            }

            @Override
            public void elementRemove(String key, Object oldValue, RemoveReason reason) {
                onRemoveNode((List<NodeInfo>) oldValue);
            }
        });
    }

    @Override
    public void onRemoveNode(List<NodeInfo> nodeInfos) {
        nodeInfos.stream().filter(nodeInfo -> nodeInfo.getNodeType() == NodeType.DB).forEach(v -> {
            port.getServices().forEach(srv -> {
                if(srv instanceof HumanObjectService objectService) {
                    if(objectService.getHumanObj().getDbPoint() != null
                            && objectService.getHumanObj().getDbPoint().nodeId.equals(v.getNodeId()) && objectService.getHumanObj().getDbPoint().portId.equals(v.getPortId())) {
                        objectService.allotDBPoint();
                    }
                }
            });
        });
    }
}
